package org.openzip.openzip.archiving.gui;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.*;
import javax.swing.filechooser.FileFilter;

import org.openzip.openzip.gui.util.IFilePanel;

/**
 * This is an implementation of <code>IFilePanel</code> for the archiving GUI.
 * Displays two fields: file name (archive name) and file path (destination
 * for the archive).
 * 
 * @author Jakub Závěrka
 */
class ArchiverFilePanel implements IFilePanel
{
	private JPanel panel;

	private JTextField filenameField;
	private JTextField filepathField;
	private JButton browseButton;

	/**
	 * Contructor. It will initialize the graphical components.
	 */
	ArchiverFilePanel(){
		filenameField = new JTextField();
		filenameField.setPreferredSize(new Dimension(150, 25));
		filepathField = new JTextField();
		filepathField.setPreferredSize(new Dimension(400, 25));
		browseButton = new JButton("Browse...");
		browseButton.setPreferredSize(new Dimension(90, 24));
		browseButton.addActionListener(new FileActionListener());

		panel = new JPanel(new BorderLayout(5, 0));

		Container filenamePanel = preparePanel("Archive name", filenameField);
		panel.add(filenamePanel, BorderLayout.WEST);

		Container filepathPanel = preparePanel("Archive path", filepathField);
		panel.add(filepathPanel);

		Container browsePanel = preparePanel(null, browseButton);
		panel.add(browsePanel, BorderLayout.EAST);
	}

	/**
	 * This is a utility method for creating a panel with certain layout.
	 * 
	 * @param label
	 *           Label
	 * @param comp
	 *           Component
	 * @return A container with provided label and component.
	 */
	private Container preparePanel(String label, JComponent comp){
		Box panel = new Box(BoxLayout.Y_AXIS);
		panel.add(Box.createVerticalGlue());

		if(label != null){
			JLabel labelText = new JLabel(label);
			labelText.setAlignmentX(JComponent.LEFT_ALIGNMENT);
			panel.add(labelText);
			// panel.add(Box.createRigidArea(gaps));
		}

		comp.setAlignmentX(JComponent.LEFT_ALIGNMENT);
		panel.add(comp);

		return panel;
	}

	/**
	 * This will return the prepared container.
	 */
	public JComponent getJComponent(){
		return panel;
	}

	/**
	 * This will make a new instance of <code>File</code> from the text fields
	 * and returns it.
	 */
	public File getFile(){
		return new File(filepathField.getText() + filenameField.getText());
	}

	/**
	 * Listener for the Browse... button.
	 */
	private class FileActionListener implements ActionListener
	{
		//One file chooser for each buton click
		JFileChooser fileChooser;
		
		FileActionListener(){
			fileChooser = new JFileChooser();
			fileChooser.setAcceptAllFileFilterUsed(false);
			//filter files to display only those with .jar suffix
			fileChooser.setFileFilter(new JarFileFilter());
		}
		/**
		 * When clicked the Browse... button, a default <code>JFileChooser</code>
		 * will be displayed. After the user picks a file, the filename and file
		 * path will be displayed in the fields. If the chosen file has not the
		 * .jar suffing, the suffix is added.
		 */
		@Override public void actionPerformed(ActionEvent e){
			fileChooser.setSelectedFile(getFile());
			if(fileChooser.showOpenDialog(panel) == JFileChooser.APPROVE_OPTION){
				File f = fileChooser.getSelectedFile();
				String filename = f.getName();
				String filepath = f.getPath().replace(filename, "");
				if(!filename.toLowerCase().endsWith(".jar")){
					filename = filename+ ".jar";
				}
				filenameField.setText(filename);
				filepathField.setText(filepath);
			}
		}
	}

	/**
	 * File filter for the file dialog. It will filter all non-jar files. 
	 */
	private class JarFileFilter extends FileFilter
	{
		/**
		 * Returns true if the specified file ends with ".jar" or the file is a 
		 * directory.
		 */
		@Override public boolean accept(File f){
			if(f.isDirectory()){
				return true;
			}
			return f.getName().toLowerCase().endsWith(".jar");
		}

		/**
		 * Returns description of JAR archives. (Returns "JAR archives".)
		 */
		@Override public String getDescription(){
			return "JAR archives";
		}
	}
}
